package com.ks.winterwarmimage;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;

import androidx.annotation.IntDef;
import androidx.annotation.Nullable;

import com.ks.winterwarmimage.menu.DropMenu;
import com.ks.winterwarmimage.mqtt.MqttMag;
import com.ks.winterwarmimage.mqtt.MsgMqttService;
import com.ks.winterwarmimage.utils.ActivityUtil;
import com.ks.winterwarmimage.utils.BasicsUtil;
import com.ks.winterwarmimage.utils.CmdDataPacket;
import com.ks.winterwarmimage.utils.Constants;
import com.ks.winterwarmimage.view.TemperatureArcView;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

public class DevControlActivity extends BaseActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
    private static final String TAG = "DevControlActivity";
    private static final String base_topic="WinterWarmImage/dev/";

    private static final String MENU_KEY_UPDATE_ACCOUNT ="menu_update_account";
    private static final String MENU_KEY_UPDATE_NAME ="menu_update_name";
    private static final String MENU_KEY_OTA ="menu_ota_update";
    private static final String MENU_KEY_REMOVE ="menu_remove";

    private TextView textTitle;
    private TextView textRelayState;
    private ImageView imgTitleMenu;
    private ImageView imageWinterWarm;
    private SeekBar seekBrightness;
    private TextView  textBrightness;
    private TextView textCurrentTemp;
     private TextView textTempSet;
    private SeekBar seekTempSet;
    //private TemperatureArcView temperatureArcView;
    private Switch switchTempAuto;
    private TextView btnShutdown;

    private Bitmap oldBitmap;
    private String deviceId;
    private DropMenu mTitleMenu=null;
    private int resultCode=0;
    /**
     * 是否改变了恒温控制状态
     */
    private boolean isControlChange=false;
    @IntDef({ControlChange.NOTHING_CHANGE,ControlChange.AUTO_RELAY_CHANGE,ControlChange.SWITCH_RELAY_CHANGE,ControlChange.TEMP_SET_CHANGE})
    @Retention(RetentionPolicy.SOURCE)
    private @interface ControlChange{
        /**无控制*/
        int NOTHING_CHANGE=0;
        /**启用该禁用自动加热*/
        int AUTO_RELAY_CHANGE=1;
        /**改变加热开关*/
        int SWITCH_RELAY_CHANGE=2;
        /**温度区间调整*/
        int TEMP_SET_CHANGE=3;
    }
    /**
     * 控制的目标
     */
    private @ControlChange int controlChange;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dev_control);
        textTitle = findViewById(R.id.text_title);
        imgTitleMenu=findViewById(R.id.img_title_menu);
        imgTitleMenu.setVisibility(View.VISIBLE);    //显示右上角菜单按钮
        textCurrentTemp= findViewById(R.id.text_current_temp);
        textRelayState=findViewById(R.id.text_relay_state);
        textRelayState.setText(getString(R.string.heating_switch)+":"+getString(R.string.off));
        //textRelayState.setSelected(true);
        imageWinterWarm=findViewById(R.id.img_winter_warm);
        seekBrightness=findViewById(R.id.seek_brightness);
        textBrightness=findViewById(R.id.text_brightness);
        textBrightness.setText(String.format( getString(R.string.light_brightness), seekBrightness.getProgress())+"%");
        switchTempAuto=findViewById(R.id.switch_temp_auto);
        btnShutdown=findViewById(R.id.btnShutdown);
        seekTempSet=findViewById(R.id.seek_temp_set);
        textTempSet=findViewById(R.id.text_temp_set);
        textTempSet.setText(String.format(getString(R.string.set_temp), seekTempSet.getProgress()));
        //textRelayState.setEnabled(false);
        findViewById(R.id.img_return).setOnClickListener(this);
        imgTitleMenu.setOnClickListener(this);
        textRelayState.setOnClickListener(this);
        btnShutdown.setOnClickListener(this);
        switchTempAuto.setOnClickListener(this);
        seekBrightness.setOnSeekBarChangeListener(this);
        seekTempSet.setOnSeekBarChangeListener(this);
        oldBitmap=((BitmapDrawable)getResources().getDrawable(R.mipmap.img_2,null)).getBitmap();
        //初始化图片亮度
        Bitmap bitmap = adjustImage(oldBitmap, -100, 0);
        imageWinterWarm.setImageBitmap(bitmap);
        if(this.getIntent().hasExtra(Constants.KEY_MAC_ID)){
            deviceId = this.getIntent().getStringExtra(Constants.KEY_MAC_ID);
        }
        if(this.getIntent().hasExtra(Constants.KEY_DEV_NAME)){
            String name = getString(R.string.title_dev_control);
            textTitle.setText(name+" - "+this.getIntent().getStringExtra(Constants.KEY_DEV_NAME));
        }else{
            textTitle.setText(R.string.title_dev_control);
        }
        bindMqttService();          //绑定MQTT服务
        if(deviceId!=null && deviceId.length()>0){
            publish(CmdDataPacket.COM_SYNC_STATE,new byte[]{0x00});  //同步状态
        }
        initRightMenu();
        setView();
    }
    private void setView(){
        Point screen=BasicsUtil.getDisplaySize(this);      //屏幕宽度
        ImageView imgHeadView = this.findViewById(R.id.image_head);
        //ImageView imgWinterWarm = this.findViewById(R.id.img_winter_warm);
        ImageView imgTailView= this.findViewById(R.id.image_tail);
        int imgHeadWidth =imgHeadView.getDrawable().getIntrinsicWidth();   //图片宽度
        int imgHeadHeight =imgHeadView.getDrawable().getIntrinsicHeight(); //图片高度
        float scale = (float) (screen.x- BasicsUtil.dp2px( this, 30))/ imgHeadWidth;  //缩放比例
        FrameLayout.LayoutParams layoutHeadParams = (FrameLayout.LayoutParams) imgHeadView.getLayoutParams();
        layoutHeadParams.width= (int) (imgHeadWidth * scale);
       // layoutHeadParams.height= (int) (imgHeadHeight * scale);
        imgHeadView.setLayoutParams(layoutHeadParams);
        int imgTailWidth =imgTailView.getDrawable().getIntrinsicWidth();   //图片宽度
        int imgTailHeight =imgTailView.getDrawable().getIntrinsicHeight(); //图片高度
        FrameLayout.LayoutParams layoutTailParams = (FrameLayout.LayoutParams) imgTailView.getLayoutParams();
        layoutTailParams.width= (int) (imgTailWidth * scale);
        imgTailView.setLayoutParams(layoutTailParams);
        int imgWinterWarmWidth = oldBitmap.getWidth() ;
        int imgWinterWarmHeight = oldBitmap.getHeight();
        scale = (float) (screen.x- BasicsUtil.dp2px( this, 30))/ imgWinterWarmWidth;  //缩放比例
        LinearLayout.LayoutParams layoutWinterWarmParams = (LinearLayout.LayoutParams) imageWinterWarm.getLayoutParams();
        layoutWinterWarmParams.width= (int) (imgWinterWarmWidth * scale);
        layoutWinterWarmParams.height= (int) (imgWinterWarmHeight * scale);
        imageWinterWarm.setLayoutParams(layoutWinterWarmParams);
    }
    @Override
    protected void onDestroy() {
        unMqttBroadcastReceiver();    //解除MQTT服务
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==REQUEST_CODE){
            if(resultCode==RESULT_CODE+2 && data!=null) {
                if (data.hasExtra(Constants.KEY_DEV_NAME)) {
                    String name = getString(R.string.title_dev_control);
                    textTitle.setText(name + " - " + data.getStringExtra(Constants.KEY_DEV_NAME));
                    this.getIntent().putExtra(Constants.KEY_DEV_NAME, data.getStringExtra(Constants.KEY_DEV_NAME));
                }
                if (data.hasExtra(Constants.KEY_MAC_ID)) {
                    deviceId = data.getStringExtra(Constants.KEY_MAC_ID);
                    this.getIntent().putExtra(Constants.KEY_MAC_ID,deviceId);
                }
                this.resultCode= resultCode;
            }else if(resultCode==RESULT_CODE+3 && data!=null){
                if (data.hasExtra(Constants.KEY_ACCOUNT_ID)) {
                    this.getIntent().putExtra(Constants.KEY_ACCOUNT_ID, data.getStringExtra(Constants.KEY_ACCOUNT_ID));
                }
                if (data.hasExtra(Constants.KEY_MAC_ID)) {
                    deviceId = data.getStringExtra(Constants.KEY_MAC_ID);
                    this.getIntent().putExtra(Constants.KEY_MAC_ID,deviceId);
                }
                this.resultCode= resultCode;
            }
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
            Log.e(TAG,"按下Back或Home键退出");
            if(resultCode!=0 && this.getIntent().getExtras()!=null)
                setResult(resultCode,this.getIntent());
            finish();
        }
        return super.onKeyDown(keyCode, event);
    }
    @Override
    public void onClick(View view) {
        if(view.getId()==R.id.img_return) {
            if(resultCode!=0 && this.getIntent().getExtras()!=null)
                setResult(resultCode,this.getIntent());
            finish();
        }else if(view.getId()==R.id.img_title_menu){
            mTitleMenu.show();
        }else if(view.getId()==R.id.btnShutdown){   //关机
            publish(CmdDataPacket.COM_OFF,new byte[]{0x00});
        }else if(view.getId()==R.id.text_relay_state){
            if(!switchTempAuto.isChecked()) {
                controlWaiting(ControlChange.SWITCH_RELAY_CHANGE);
                //改变加热继电器状态，view.isSelected()的状态代表了当前继电器状态，所以发送的状态字应取反
                publish(CmdDataPacket.COM_SWITCH_RELAY, new byte[]{view.isSelected() ? (byte) 0x00 : (byte) 0x01});
            }
        }else if(view.getId()==R.id.switch_temp_auto){
            controlWaiting(ControlChange.AUTO_RELAY_CHANGE);
            publish(CmdDataPacket.COM_TEMP_CONTROL, new byte[]{((Switch)view).isChecked()? (byte) 0x01 : (byte) 0x00});
            switchTempAuto.setText(switchTempAuto.isChecked()?R.string.temp_control_enable: R.string.temp_control_disable);
        }
    }
    /**
     * 滑动条进度改变监听
     */
    @SuppressLint("StringFormatInvalid")
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        String resString = null;
        if(seekBar.getId()==R.id.seek_brightness) {
            if (oldBitmap != null) {
                Bitmap bitmap = adjustImage(oldBitmap, progress - 100, 0);
                imageWinterWarm.setImageBitmap(bitmap);
                resString= getString(R.string.light_brightness);
                textBrightness.setText(String.format( resString, progress)+"%");
            }
        }else  if(seekBar.getId()==R.id.seek_temp_set) {
             resString= getString(R.string.set_temp);
            textTempSet.setText( String.format(resString, progress));
        }
    }
    /**
     * 滑动条开始滑动监听
     */
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }
    /**
     * 滑动条停止滑动监听
     */
    @SuppressLint("StringFormatInvalid")
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int progress=seekBar.getProgress();
        byte com=0;
        byte[] send_buff=null;
         if(seekBar.getId()==R.id.seek_brightness) {
             com=CmdDataPacket.COM_ILLUMINATE_IMAGE_SET;
             send_buff=new byte[]{(byte) progress};
             String brightness=getString(R.string.light_brightness);
             textBrightness.setText(String.format(brightness,progress)+"%");
        }else  if(seekBar.getId()==R.id.seek_temp_set) {
             com=CmdDataPacket.COM_TEMP_SET;
             send_buff=new byte[]{(byte) ((byte) progress>1?progress-1:0), (byte) ((byte) progress)};//按照设定值左右偏差1°C
             String temp=getString(R.string.set_temp);
             textTempSet.setText(String.format(temp,progress));
        }
        //发送命令
        if(send_buff!=null) {
            publish(com, send_buff);
        }
    }
    /**
     * 接收消息处理
     * @param message
     */
    @Override
    protected void onMessageArrived(MqttMag message) {
        super.onMessageArrived(message);
        String topic = message.getTopic().replace(base_topic, "");  //去掉基主题部分
        String id= BasicsUtil.removeMacColon(deviceId);    //去除冒号
        if(id.equalsIgnoreCase(topic)){    //收到的消息和群组号一致
            receiveAnalysis(message.getMessage(),deviceId);
        }
    }
    /**初始化右上角弹出菜单*/
    private void initRightMenu(){
        mTitleMenu=new DropMenu(this,imgTitleMenu, Gravity.END);
        mTitleMenu.addMenuItem(MENU_KEY_UPDATE_ACCOUNT,R.string.update_account,R.drawable.ic_account_24dp);
        mTitleMenu.addMenuItem(MENU_KEY_UPDATE_NAME,R.string.update_dev_name,R.drawable.ic_dev_24dp);
        mTitleMenu.addSplitLine(2);
        mTitleMenu.addMenuItem(MENU_KEY_OTA,R.string.title_ota,R.drawable.ic_ota_24);
//        mTitleMenu.addSplitLine(4);
//        mTitleMenu.addMenuItem(MENU_KEY_REMOVE,R.string.title_remove_dev,R.drawable.ic_dell_24dp);
        mTitleMenu.setMenuItemIconTint(Color.GRAY);
        mTitleMenu.setMenuItemBackgroundResource(R.drawable.button_style);//设置菜单项目背景样式
        mTitleMenu.setOnMenuItemClickListener((item, view) -> {
            Bundle bundle=this.getIntent().getExtras();
            switch (item.getItemKey()){
                case MENU_KEY_UPDATE_ACCOUNT:
                    ActivityUtil.startActivity(DevControlActivity.this, UpdateAccountActivity.class,REQUEST_CODE,bundle);
                    break;
                case MENU_KEY_UPDATE_NAME:
                    ActivityUtil.startActivity(DevControlActivity.this, UpdateDeviceNameActivity.class,RESULT_CODE,bundle);
                    break;
                case MENU_KEY_OTA:
                    ActivityUtil.startActivity(DevControlActivity.this, OtaUpgradeActivity.class,REQUEST_CODE,bundle);
                    break;
                case MENU_KEY_REMOVE:
                    break;
            }
        });
    }
    /**
     * 发送命令
     * @param com 命令字
     * @param data 数据
     */
    private void publish(byte com,byte[] data){
        CmdDataPacket dataPacket=new CmdDataPacket(com,data);
        String id=BasicsUtil.removeMacColon(deviceId).toUpperCase();    //去除冒号
        String topic="WinterWarmImage/phone/"+id;//"/topic/mesh_cmd/"+group+"/"+childId;
        MsgMqttService.publish(topic,dataPacket.toBytes(),0,false);
    }
    /**
     * 接收解析处理
     * @param data
     * @param id
     */
    private void receiveAnalysis(byte[] data,String id) {
        if(id!=null) {
            CmdDataPacket cmdDataPacket = CmdDataPacket.fromBytes(data);  //将消息转为标准命令结构
            if(cmdDataPacket!=null) {
                if (cmdDataPacket.command == CmdDataPacket.COM_ILLUMINATE_IMAGE_GET_ACK) {
                    seekBrightness.setProgress(cmdDataPacket.data[0]);
                    if (!btnShutdown.isEnabled()) btnShutdown.setEnabled(true);
                } else if (cmdDataPacket.command == CmdDataPacket.COM_UPLOAD_TEMP) {
                    //表示小字节序字节顺序的常数。按此顺序，多字节值的字节从最低有效到最高有效排序。
                    ByteBuffer buffer = ByteBuffer.wrap(cmdDataPacket.data).order(ByteOrder.LITTLE_ENDIAN);
                    float currentTemp = buffer.getFloat();
                    textCurrentTemp.setText(String.format("%.1f℃", currentTemp));
                    if (!btnShutdown.isEnabled()) btnShutdown.setEnabled(true);
                } else if (cmdDataPacket.command == CmdDataPacket.COM_TEMP_GET_ACK) {
                    byte minTemp = cmdDataPacket.data[0];                 //高低温区间下限
                    byte maxTemp = cmdDataPacket.data[1];                 //高低温区间上限
                    seekTempSet.setProgress(maxTemp);//minTemp+(maxTemp-minTemp)/2);
                    if (!btnShutdown.isEnabled()) btnShutdown.setEnabled(true);
                } else if (cmdDataPacket.command == CmdDataPacket.COM_SYNC_STATE
                        || cmdDataPacket.command == CmdDataPacket.COM_SYNC_STATE_ACK) {
                    if (cmdDataPacket.data.length > 8) {
                        //表示小字节序字节顺序的常数。按此顺序，多字节值的字节从最低有效到最高有效排序。
                        byte[] temp_data = BasicsUtil.subByte(cmdDataPacket.data, 0, 4);
                        ByteBuffer buffer = ByteBuffer.wrap(temp_data).order(ByteOrder.LITTLE_ENDIAN);
                        float currentTemp = buffer.getFloat();                      //温度
                        byte relayState = cmdDataPacket.data[4];              //继电器状态
                        boolean isAutoRelay = cmdDataPacket.data[5] == 1;    //是否由温度区间控制
                        byte brightness = cmdDataPacket.data[6];              //照明灯亮度
                        byte minTemp = cmdDataPacket.data[7];                 //高低温区间下限
                        byte maxTemp = cmdDataPacket.data[8];                 //高低温区间上限
                        textCurrentTemp.setText(String.format("%.1f℃", currentTemp));
                        seekTempSet.setProgress(maxTemp);//minTemp+(maxTemp-minTemp)/2);
                        textRelayState.setSelected(relayState == 1);
                        textRelayState.setEnabled(!isAutoRelay);   //自动继电器控制时禁止点击
                        //textRelayState.setText(relayState == 1 ? R.string.on : R.string.off);
                        textRelayState.setText(getString(R.string.heating_switch)+":"+getString(relayState == 1 ? R.string.on : R.string.off));
                        switchTempAuto.setChecked(isAutoRelay);
                        switchTempAuto.setText(isAutoRelay?R.string.temp_control_enable:R.string.temp_control_disable);
                        seekBrightness.setProgress(brightness); //照画灯亮度
                    }
                    if (!btnShutdown.isEnabled()) btnShutdown.setEnabled(true);
                } else if (cmdDataPacket.command == CmdDataPacket.COM_OFF ||
                        cmdDataPacket.command == CmdDataPacket.COM_OFF_ACK) {
                    btnShutdown.setEnabled(false);
                    seekBrightness.setProgress(0);
                    seekTempSet.setProgress(0);
                    textRelayState.setSelected(false);
                    textRelayState.setEnabled(false);   //自动继电器控制时禁止点击
                    //textRelayState.setText( R.string.off);
                    textRelayState.setText(getString(R.string.heating_switch)+":"+getString( R.string.off));
                } else if (cmdDataPacket.command == CmdDataPacket.COM_TEMP_CONTROL_ACK) {
                    if (cmdDataPacket.data.length > 1) {
                        boolean auto_relay = cmdDataPacket.data[0] == 1;
                        boolean is_relay_on = cmdDataPacket.data[1] == 1;
                        textRelayState.setEnabled(!auto_relay);
                        textRelayState.setSelected(is_relay_on);
                        //textRelayState.setText(is_relay_on ? R.string.on : R.string.off);
                        textRelayState.setText(getString(R.string.heating_switch)+":"+getString(is_relay_on ? R.string.on : R.string.off));
                    }
                    this.endWaiting();
                } else if (cmdDataPacket.command == CmdDataPacket.COM_TEMP_SET_ACK) {
                    this.endWaiting();
                } else if (cmdDataPacket.command == CmdDataPacket.COM_SWITCH_RELAY_ACK
                        || cmdDataPacket.command == CmdDataPacket.COM_UPLOAD_RELAY_STAT) {
                    boolean is_relay_on = cmdDataPacket.data[0] == 1;
                    textRelayState.setSelected(is_relay_on);  //状态改变应答，取反
                    //textRelayState.setText(is_relay_on ? R.string.on : R.string.off);
                    textRelayState.setText(getString(R.string.heating_switch)+":"+getString(is_relay_on ? R.string.on : R.string.off));
                    if (cmdDataPacket.command == CmdDataPacket.COM_SWITCH_RELAY_ACK) {
                        this.endWaiting();
                    }
                }
            }
        }
    }
    /**
     * 调整亮度和对比度
     * @param src 图片
     * @param brightness 亮度(-100 智 100，默认0不改变亮度)
     * @param contrast 对比度(-100 智 100，默认0不改变饱和度)
     * @return
     */
    public Bitmap adjustImage(Bitmap src, float brightness, float contrast) {
        Bitmap dest = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
        // 创建颜色矩阵组合
        ColorMatrix cm = new ColorMatrix();
        // 对比度矩阵（缩放因子）
        float scale = contrast + 1.f;
        float translate = (-0.5f * scale + 0.5f) * 255.f;
        cm.set(new float[] {
                scale, 0, 0, 0, translate,
                0, scale, 0, 0, translate,
                0, 0, scale, 0, translate,
                0, 0, 0, 1, 0
        });
        // 亮度调整（叠加平移）
        ColorMatrix brightnessMatrix = new ColorMatrix();
        brightnessMatrix.set(new float[] {
                1, 0, 0, 0, brightness,
                0, 1, 0, 0, brightness,
                0, 0, 1, 0, brightness,
                0, 0, 0, 1, 0
        });
        // 合并矩阵
        cm.postConcat(brightnessMatrix);
        // 应用滤镜
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        Canvas canvas = new Canvas(dest);
        canvas.drawBitmap(src, 0, 0, paint);
        return dest;
    }
    /**
     * 控制超时等待
     * @param controlChange
     */
    private void controlWaiting(@ControlChange int controlChange){
        isControlChange=true;
        this.controlChange=controlChange;
        textTitle.postDelayed(runnableWaiting,1000);
    }
    /**
     * 结束超时等待
     */
    private void endWaiting(){
        textTitle.removeCallbacks(runnableWaiting);
        isControlChange=false;
        DevControlActivity.this.controlChange=ControlChange.NOTHING_CHANGE;
    }
    /**
     * 控制超时任务
     */
    private Runnable runnableWaiting=()->{
        //控制超时
        isControlChange=false;
        DevControlActivity.this.controlChange=ControlChange.NOTHING_CHANGE;
    };
}